/**
 * 所有版权归 广西梧州 陈锦韬 所有
 *
 * @Title: SystemHandler
 * @Package com.rx.uua.handler
 * @Description: 关于系统管理的处理
 * @author: 陈锦韬
 * @date: 2021\7\7 0007
 * @version V1.0
 * @Copyright: 2021 陈锦韬  All rights reserved.
 */
package com.rx.uua.handler;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.rx.core.anno.RxAlias;
import com.rx.core.base.RxBaseConstant;
import com.rx.core.base.RxBaseData;
import com.rx.core.base.RxResponse;
import com.rx.core.bean.LoginUserInfo;
import com.rx.core.bean.RxBCryptPasswordEncoder;
import com.rx.core.enm.*;
import com.rx.core.handler.*;
import com.rx.core.iface.RelationQuery;
import com.rx.core.iface.ReturnInputMode;
import com.rx.core.service.StandardService;
import com.rx.core.util.EmptyChecker;
import com.rx.core.util.RxContentHolder;
import com.rx.core.util.RxUtil;
import com.rx.uua.enm.RELATION_TYPE;
import com.rx.uua.service.SystemService;
import com.rx.uua.vo.*;
import com.rx.uua.vo.relation.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCrypt;

import javax.management.relation.RelationType;
import javax.validation.Path;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author: Administrator
 * @Description: 关于系统管理的处理
 * @date: 2021\7\7 0007
 */
@RxHandler
@Slf4j
public class SystemHandler implements RxHandlerContent {
    public static final String  RANDOM_PASSWORD="RANDOM_PASSWORD";

    @Autowired
    StandardService standardService;

    @Autowired
    SystemService systemService;

    @Override
    public boolean handle(RxBaseData data) {
        return false;
    }

    /**
     * 随机生成密码
     * @param data
     * @return
     */
    @RxHandlerPrev(types= {HANDLER_TYPE.SINGLE_INSERT,HANDLER_TYPE.DOUBLE_INSERT},keys = {
        "/rx-standard-api/single/uua-user-info/standard/insert",
        "/rx-standard-api/double/uua-user-info/uua-rel-user-org/insert"
    })
    public boolean generatePassword(RxBaseData data){
        UuaUserInfo uuaUserInfo = (UuaUserInfo)data;

        if(RX_USER_TYPE.SYS.getCode().equalsIgnoreCase(uuaUserInfo.getUserType())||RX_USER_TYPE.ADMIN.getCode().equalsIgnoreCase(uuaUserInfo.getUserType())){
            if(!RxContentHolder.systemUser()){
                data.setResultMessage("只有系统用户才能新增系统用户");
                return true;
            }
        }

        String password = RandomStringUtils.randomAlphanumeric(6);
        uuaUserInfo.setTmpVar(RANDOM_PASSWORD,password);
        String pwd = RxBCryptPasswordEncoder.E_PREFIX + password + RxBCryptPasswordEncoder.E_SUFFIX;
        String enPwd = BCrypt.hashpw(pwd,BCrypt.gensalt());
        uuaUserInfo.setPassword(enPwd);
        log.info("随机生成密码");

        return false;
    }

    /**
     * 将密码返回前端
     * @param data
     * @return
     */
    @RxHandlerAfter(types= {HANDLER_TYPE.SINGLE_INSERT,HANDLER_TYPE.DOUBLE_INSERT},keys = {
            "/rx-standard-api/single/uua-user-info/standard/insert",
            "/rx-standard-api/double/uua-user-info/uua-rel-user-org/insert"
    })
    public boolean returnPassword(RxBaseData data){
        String password = (String)data.getTmpVar(RANDOM_PASSWORD);
        AddUserReturn addUserReturn = new AddUserReturn();
        StringBuffer sb=new StringBuffer(password);
        addUserReturn.setPassString(sb.reverse().toString());
        addUserReturn.setUserName(((UuaUserInfo)data).getUserName());
        data.setResultData(addUserReturn);

        return false;
    }

    private List<String> getInputBidList(RxBaseData data){
        List<String> userBidList = new ArrayList<>();
        if (EmptyChecker.isEmpty(data.getDataList())){
            UuaRelUserOrg uuaRelUserOrg = (UuaRelUserOrg)data;
            userBidList.add(uuaRelUserOrg.getItemBid());
        }else {
            for (RxBaseData rxBaseData : data.getDataList()) {
                UuaRelUserOrg uuaRelUserOrg = (UuaRelUserOrg)rxBaseData;
                userBidList.add(uuaRelUserOrg.getItemBid());
            }
        }
        return userBidList;
    }

    /**
     * 条件
     * @return
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private RxBaseData makeCondition(List<String> userBidList,HANDLER_TYPE handlerType) throws InstantiationException, IllegalAccessException {
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("inItemBid",userBidList);
        RxBaseData condition = RxBaseData.create(UuaRelUserOrg.class, handlerType);
        condition.setCondition(conditionMap);
        return condition;
    }

    private void updateOrgFlg(String orgFlg,List<String> userBidList) throws InstantiationException, IllegalAccessException {
        if (EmptyChecker.isEmpty(userBidList)){
            return;
        }
        for (String s : userBidList) {
            log.info("bid:" + s);
        }
        UuaUserInfo conditionUser = (UuaUserInfo)RxBaseData.create(UuaUserInfo.class,HANDLER_TYPE.SINGLE_UPDATE);
        conditionUser.setOrgFlg(orgFlg);
        Map<String,Object> conditionUserMap = new HashMap<>();
        conditionUserMap.put("inBid",userBidList);
        conditionUser.setCondition(conditionUserMap);
        // 更新状态
        Object updateCount = standardService.update(conditionUser);
        if(EmptyChecker.isEmpty(updateCount)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.MESSAGE,"更新ORG_FLG失败");
        }
    }
    /**
     * 根据对表uua_rel_user_org 的操作更新表uua_user_info 的org_flg标记
     * @param data
     * @return
     */
    @RxHandlerAfter(types= {
            HANDLER_TYPE.SINGLE_INSERT,
            HANDLER_TYPE.SINGLE_DELETE,
            HANDLER_TYPE.SINGLE_BATCH_DELETE,
            HANDLER_TYPE.SINGLE_BATCH_INSERT
    },keys = {
        "/rx-standard-api/single/uua-rel-user-org/standard/insert",
        "/rx-standard-api/single/uua-rel-user-org/standard/delete",
        "/rx-standard-api/single/uua-rel-user-org/standard/batch-insert",
        "/rx-standard-api/single/uua-rel-user-org/standard/batch-delete"
    })
    public boolean updateOrgFlg(RxBaseData data){

        // 查询
        try {
            if (data instanceof UuaRelUserOrg) {
                UuaRelUserOrg uuaRelUserOrg = (UuaRelUserOrg)data;
                if(RELATION_TYPE.USER_ADMIN.getValue().equalsIgnoreCase(uuaRelUserOrg.getRelationType())){
                    // 管理人员授权 不用更新用户表
                    return false;
                }
            }else if (EmptyChecker.notEmpty(data.getDataList())) {
                for (RxBaseData rxBaseData : data.getDataList()) {
                    UuaRelUserOrg uuaRelUserOrg = (UuaRelUserOrg)rxBaseData;
                    if(RELATION_TYPE.USER_ADMIN.getValue().equalsIgnoreCase(uuaRelUserOrg.getRelationType())){
                        // 管理人员授权 不用更新用户表
                        return false;
                    }
                }
            }

            boolean isDelete = false;
            if (data.getUrlAnalyse().getMethod().contains("delete")){
                isDelete = true;
            }
            // 获取输入的用户bid
            List<String> userBidList = getInputBidList(data);
            if (!isDelete){
                updateOrgFlg(RX_ORG_FLG.HAVE.getCode(),userBidList);
                return false;
            }


            RxBaseData condition = makeCondition(userBidList,HANDLER_TYPE.SINGLE_LIST);
            log.info("类" + condition.getClass().getSimpleName());
            Object object = standardService.searchList(condition);
            if (object instanceof RxResponse) {
                data.setResultMessage("列表返回数据为空");
            }else{
                List<UuaRelUserOrg> resultList = (List<UuaRelUserOrg>)object;
                if (EmptyChecker.notEmpty(resultList)){
                    List<String> haveList = resultList.stream().map(UuaRelUserOrg::getItemBid).collect(Collectors.toList());
                    userBidList.removeAll(haveList);
                }
            }

            updateOrgFlg(RX_ORG_FLG.NONE.getCode(),userBidList);
        }catch (IllegalAccessException | InstantiationException e) {
            RxUtil.CheckUtil.throwOut(RESULT_CODE.MESSAGE,"更新ORG_FLG失败");
        }



        return false;
    }

    private List<String> getInputRoleBidList(RxBaseData data){
        List<String> userBidList = new ArrayList<>();
        if (EmptyChecker.isEmpty(data.getDataList())){
            UuaRelGroup uuaRelUserOrg = (UuaRelGroup)data;
            userBidList.add(uuaRelUserOrg.getItemBid());
            userBidList.add(uuaRelUserOrg.getGroupBid());
        }else {
            for (RxBaseData rxBaseData : data.getDataList()) {
                UuaRelGroup uuaRelUserOrg = (UuaRelGroup)rxBaseData;
                userBidList.add(uuaRelUserOrg.getItemBid());
                userBidList.add(uuaRelUserOrg.getGroupBid());
            }
        }
        return userBidList.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 更改冲突标记
     * @param orgFlg
     * @param roleBidList
     * @throws InstantiationException
     * @throws IllegalAccessException
     */
    private void updateConflictFlg(String orgFlg,List<String> roleBidList) throws InstantiationException, IllegalAccessException {
        if (EmptyChecker.isEmpty(roleBidList)){
            return;
        }
        for (String s : roleBidList) {
            log.info("bid:" + s);
        }
        UuaRoleInfo conditionUser = (UuaRoleInfo)RxBaseData.create(UuaRoleInfo.class,HANDLER_TYPE.SINGLE_UPDATE);
        conditionUser.setConflict(orgFlg);
        Map<String,Object> conditionUserMap = new HashMap<>();
        conditionUserMap.put("inBid",roleBidList);
        conditionUser.setCondition(conditionUserMap);
        // 更新状态
        Object updateCount = standardService.update(conditionUser);
        if(EmptyChecker.isEmpty(updateCount)){
            RxUtil.CheckUtil.throwOut(RESULT_CODE.MESSAGE,"更新Conflict失败");
        }
    }

    private boolean RelationTypeFilter(RxBaseData data){
        if (EmptyChecker.isEmpty(data.getDataList())){
            UuaRelGroup uuaRelUserOrg = (UuaRelGroup)data;
            if (RELATION_TYPE.ROLE_TO_ROLE.getValue().equalsIgnoreCase(uuaRelUserOrg.getRelationType())){
                // 不是冲突放过
                return false;
            }
        }else {
            for (RxBaseData rxBaseData : data.getDataList()) {
                UuaRelGroup uuaRelUserOrg = (UuaRelGroup)rxBaseData;
                if (RELATION_TYPE.ROLE_TO_ROLE.getValue().equalsIgnoreCase(uuaRelUserOrg.getRelationType())){
                    // 不是冲突放过
                    return false;
                }
            }
        }
        return true;
    }


    /**
     * 根据对表uua_rel_group 的操作更新表uua_role_info 的conflict标记
     * @param data
     * @return
     */
    @RxHandlerAfter(types= {
            HANDLER_TYPE.SINGLE_INSERT,
            HANDLER_TYPE.SINGLE_DELETE,
            HANDLER_TYPE.SINGLE_BATCH_DELETE,
            HANDLER_TYPE.SINGLE_BATCH_INSERT
    },keys = {
            "/rx-standard-api/single/uua-rel-group/standard/insert",
            "/rx-standard-api/single/uua-rel-group/standard/delete",
            "/rx-standard-api/single/uua-rel-group/standard/batch-insert",
            "/rx-standard-api/single/uua-rel-group/standard/batch-delete"
    })
    public boolean updateConflict(RxBaseData data){

        // 查询
        try {
            if (RelationTypeFilter(data)){
                // 不是冲突放过
                return false;
            }

            boolean isDelete = false;
            if (data.getUrlAnalyse().getMethod().contains("delete")){
                isDelete = true;
            }
            // 获取输入的用户bid
            List<String> roleBidList = getInputRoleBidList(data);
            if (!isDelete){
                updateConflictFlg(RX_CONFLICT_FLG.HAVE.getCode(),roleBidList);
                return false;
            }
            List<UuaRelGroup> resultList = systemService.getConflictRoleList(roleBidList,null);
            if (EmptyChecker.notEmpty(resultList)){
                List<String> haveList = resultList.stream().map(UuaRelGroup::getGroupBid).collect(Collectors.toList());
                roleBidList.removeAll(haveList);
                List<String> itemList = resultList.stream().map(UuaRelGroup::getItemBid).collect(Collectors.toList());
                roleBidList.removeAll(itemList);
            }

            updateConflictFlg(RX_CONFLICT_FLG.NONE.getCode(),roleBidList);

        }catch (IllegalAccessException | InstantiationException e) {
            RxUtil.CheckUtil.throwOut(RESULT_CODE.MESSAGE,"更新ORG_FLG失败");
        }
        return false;
    }


    @RxHandlerAfter(types= {
            HANDLER_TYPE.DOUBLE_LIST,
            HANDLER_TYPE.DOUBLE_PAGE
    },keys = {
            "/rx-standard-api/double/uua-user-info/uua-rel-user-org/inner-search-page",
            "/rx-standard-api/double/uua-user-info/uua-rel-user-org/inner-search-list"
    })
    public boolean filterOrg(RxBaseData data){
        RelationQuery relationQuery = (RelationQuery)data;

        List<LoginUserInfo.OrgInfo> orgInfoList = RxContentHolder.getOrgInfo();
        LoginUserInfo.UserInfo userInfo = RxContentHolder.getUserInfo();
        if (EmptyChecker.isEmpty(orgInfoList) && !RX_USER_TYPE.SYS.getCode().equalsIgnoreCase(userInfo.getUserType()) ){
            // 无授权。
            data.setResultMessage("该用户未加入机构");
            return true;
        }
        List<String> orgBidList = orgInfoList.stream().map(e->e.getBid()).collect(Collectors.toList());
        if (RxContentHolder.hasRole(RX_ROLE.MANAGER.getCode())){
            orgBidList.addAll(systemService.getOrgListFromDb(userInfo.getBid(),(e)->{
                return ((UuaOrgInfo)e).getBid();
            }));
        }
        UuaRelUserOrg uuaRelUserOrg = (UuaRelUserOrg) relationQuery.obtainRelation();
        RxUtil.CheckUtil.check(uuaRelUserOrg,RESULT_CODE.MESSAGE,"无关联条件");
        if (EmptyChecker.notEmpty(uuaRelUserOrg.getGroupBid())){
           if (!orgBidList.contains(uuaRelUserOrg.getGroupBid()) && !RX_USER_TYPE.SYS.getCode().equalsIgnoreCase(userInfo.getUserType()) && !hasRoleCando()){
               // 无授权
               data.setResultMessage("该用户无授权");
               return true;
           }
        }else{
            Map<String,Object> conditionMap = uuaRelUserOrg.getCondition();
            if (EmptyChecker.notEmpty(conditionMap)){
                Object object = conditionMap.get("inGroupBid");
                if (EmptyChecker.notEmpty(object)){
                    List<String> list = JSONArray.parseArray(JSONArray.toJSONString(object),String.class);
                    orgBidList.retainAll(list);
                }
            }
            conditionMap.put("inGroupBid",orgBidList);
        }
        QueryWrapper queryWrapper = data.queryWrapper(false);
        data.setTmpVar(RxBaseConstant.RESULT_QUERY_KEY,queryWrapper);
        return false;
    }

    @RxHandlerPrev(types= {
            HANDLER_TYPE.SINGLE_LIST,
            HANDLER_TYPE.SINGLE_PAGE,
            HANDLER_TYPE.DOUBLE_LEFT_PAGE
    },keys = {
            "/rx-standard-api/single/uua-role-info/standard/page",
            "/rx-standard-api/single/uua-role-info/standard/search-list",
            "/rx-standard-api/double/uua-role-info/uua-rel-user-role/left-search-page",
            "/rx-standard-api/double/uua-role-info/uua-rel-group/left-search-page",
    })
    @RxAlias("orgPermission")
    public boolean filterRoleForManager(RxBaseData data){
        LoginUserInfo.UserInfo userInfo = RxContentHolder.getUserInfo();
        // 系统用户。不过滤
        if (RX_USER_TYPE.SYS.getCode().equalsIgnoreCase(userInfo.getUserType())){
            return false;
        }
        final String KEY = "inRoleCode";
        List<String> roleCodeList = data.conditionList(KEY);
        if(RxContentHolder.hasRole(RX_ROLE.MANAGER.getCode())){
            // 授权管理的机构不会很多。

            List<DoubleUuaRoleInfo> adminRoleList = null;
            try {
                adminRoleList = systemService.getRoleListForAdmin(null,userInfo.getBid());
                roleCodeList.addAll(adminRoleList.stream()
                        .map(e->e.getRoleCode())
                        .collect(Collectors.toList()));
                if(EmptyChecker.isEmpty(roleCodeList)){
                    data.setResultMessage("未授权角色");
                    return true;
                }

            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        }
        data.conditionDistinct(KEY);
        return false;
    }
    @RxHandlerPrev(types= {
            HANDLER_TYPE.SINGLE_LIST,
            HANDLER_TYPE.SINGLE_PAGE,
            HANDLER_TYPE.DOUBLE_LEFT_PAGE
    },keys = {
            "/rx-standard-api/single/uua-post-info/standard/page",
            "/rx-standard-api/single/uua-post-info/standard/search-list",
            "/rx-standard-api/double/uua-post-info/uua-rel-user-post/left-search-page",
            "/rx-standard-api/double/uua-post-info/uua-rel-group/left-search-page",
    })
    @RxAlias("orgPermission")
    public boolean filterPostForManager(RxBaseData data){
        LoginUserInfo.UserInfo userInfo = RxContentHolder.getUserInfo();
        // 系统用户。不过滤
        if (RX_USER_TYPE.SYS.getCode().equalsIgnoreCase(userInfo.getUserType())){
            return false;
        }
        final String KEY = "inPostCode";
        List<String> postCodeList = data.conditionList(KEY);
        if(RxContentHolder.hasRole(RX_ROLE.MANAGER.getCode())){
            // 授权管理的机构不会很多。
            List<DoubleUuaPostInfo> adminPostList = null;
            try {
                adminPostList = systemService.getPostListForAdmin(null,userInfo.getBid());
                postCodeList.addAll(adminPostList.stream()
                        .map(e->e.getPostCode())
                        .collect(Collectors.toList()));
                if(EmptyChecker.isEmpty(postCodeList)){
                    data.setResultMessage("未授权岗位");
                    return true;
                }

            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }

        }
        data.conditionDistinct(KEY);
        return false;
    }

    private boolean judgeClassCode(UuaOrgInfo orgInfo){
        if(RX_CLASS_CODE.ORG.getCode().equalsIgnoreCase(orgInfo.getClassCode())){
            return true;
        }
        if(RX_CLASS_CODE.INNER_ORG.getCode().equalsIgnoreCase(orgInfo.getClassCode())){
            return true;
        }
        return false;
    }

    private boolean hasRoleCando(){
        if(RxContentHolder.hasRole(RX_ROLE.STEACHING.getCode())){
            return true;
        }
        if(RxContentHolder.hasRole(RX_ROLE.TEACHER.getCode())){
            return true;
        }
        if(RxContentHolder.hasRole(RX_ROLE.CLASS_MANAGE.getCode())){
            return true;
        }
        return false;
    }


    @RxHandlerPrev(types= {
            HANDLER_TYPE.SINGLE_LIST,
            HANDLER_TYPE.SINGLE_PAGE,
            HANDLER_TYPE.DOUBLE_LEFT_PAGE
    },keys = {
            "/rx-standard-api/single/uua-org-info/standard/page",
            "/rx-standard-api/single/uua-org-info/standard/search-list",
            "/rx-standard-api/double/uua-org-info/uua-rel-user-org/left-search-page"
    })
    @RxAlias("orgPermission")
    public boolean filterOrgForManager(RxBaseData data){
        LoginUserInfo.UserInfo userInfo = RxContentHolder.getUserInfo();
        // 系统用户。不过滤
        if (RX_USER_TYPE.SYS.getCode().equalsIgnoreCase(userInfo.getUserType())){
            return false;
        }

        List<LoginUserInfo.OrgInfo> orgInfoList = RxContentHolder.getOrgInfo();
        if (EmptyChecker.isEmpty(orgInfoList)){
            // 无授权。
            data.setResultMessage("该用户未加入机构");
            return true;
        }
        final String KEY = "inOrgCode";
        List<String> orgCodeList = data.conditionList(KEY);
        if(RxContentHolder.hasRole(RX_ROLE.MANAGER.getCode())){
            // 授权管理的机构不会很多。
            orgCodeList.addAll(systemService.getOrgListFromDb(userInfo.getBid(),(e)->{
                return ((UuaOrgInfo)e).getOrgCode();
            }));
            UuaOrgInfo orgInfo = (UuaOrgInfo)data;
            if(judgeClassCode(orgInfo)){
                orgInfo.setClassCode(null);
            }

            data.setReturnType(RX_RETURN_TYPE.TREE.getCode());

        }
        if (EmptyChecker.isEmpty(orgCodeList) && !hasRoleCando()){
            // 无授权。
            data.setResultMessage("未授权机构");
            return true;
        }

        data.conditionDistinct(KEY);
        return false;
    }
}
